package com.ruicar.afs.cloud.afscase.loansuspendrule.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruicar.afs.cloud.afscase.approvetask.entity.CaseApproveRecord;
import com.ruicar.afs.cloud.afscase.approvetask.service.CaseApproveRecordService;
import com.ruicar.afs.cloud.afscase.autoaudit.service.impl.RuleAtomDataService;
import com.ruicar.afs.cloud.afscase.infomanagement.entity.CaseBaseInfo;
import com.ruicar.afs.cloud.afscase.infomanagement.entity.CaseContractInfo;
import com.ruicar.afs.cloud.afscase.infomanagement.service.CaseBaseInfoService;
import com.ruicar.afs.cloud.afscase.infomanagement.service.CaseContractInfoService;
import com.ruicar.afs.cloud.afscase.loanapprove.entity.CasePriorityRecord;
import com.ruicar.afs.cloud.afscase.loanapprove.service.CasePriorityChangeService;
import com.ruicar.afs.cloud.afscase.loanapprove.service.CasePriorityRecordService;
import com.ruicar.afs.cloud.afscase.loansuspendrule.entity.LoanSuspendRule;
import com.ruicar.afs.cloud.afscase.loansuspendrule.mapper.LoanSuspendRuleMapper;
import com.ruicar.afs.cloud.afscase.loansuspendrule.service.LoanSuspendRuleService;
import com.ruicar.afs.cloud.afscase.mq.approvesendinfo.service.ApproveLoanInfoService;
import com.ruicar.afs.cloud.afscase.risk.service.CaseTortoiseService;
import com.ruicar.afs.cloud.bizcommon.rules.entity.AfsRuleInfo;
import com.ruicar.afs.cloud.bizcommon.rules.service.AfsRuleInfoService;
import com.ruicar.afs.cloud.common.core.enums.AfsEnumUtil;
import com.ruicar.afs.cloud.common.core.security.service.AfsUser;
import com.ruicar.afs.cloud.common.core.security.util.SecurityUtils;
import com.ruicar.afs.cloud.common.core.util.SpringContextHolder;
import com.ruicar.afs.cloud.common.modules.afscorebusiness.enums.*;
import com.ruicar.afs.cloud.common.rules.RuleHelper;
import com.ruicar.afs.cloud.common.rules.dto.RuleRunResult;
import com.ruicar.afs.cloud.risk.api.enums.tortoise.GwtTortoiseAntiFraudCallStep;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.annotations.Case;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.PathVariable;

import java.util.*;

/**
 * @author: yk.Li
 * @date 2020-06-09 07:44:18
 * @description 暂停放款规则信息表  service实现类
 */
@Service
@AllArgsConstructor
@Data
@Slf4j
public class LoanSuspendRuleServiceImpl extends ServiceImpl<LoanSuspendRuleMapper, LoanSuspendRule> implements LoanSuspendRuleService {
    private AfsRuleInfoService afsRuleInfoService;
    private RuleAtomDataService ruleAtomDataService;
    private CaseContractInfoService caseContractInfoService;
    private CasePriorityRecordService casePriorityRecordService;
    private CaseBaseInfoService caseBaseInfoService;
    private CaseApproveRecordService caseApproveRecordService;
    private ApproveLoanInfoService approveLoanInfoService;
    private CaseTortoiseService caseTortoiseService;
    private CasePriorityChangeService casePriorityChangeService;

    /**
     * @param
     * @description 通过业务规则id批量失效规则
     * @author yk.Li
     * @date 2020/7/6
     */
    @Override
    public void deActiveRuleByRuleNo(String[] ids) {
        //使规则失效
        for (String id : ids) {
            LoanSuspendRule loanSuspendRule = this.getById(id);
            if (null != loanSuspendRule) {
                AfsRuleInfo afsRuleInfo = afsRuleInfoService.getById(loanSuspendRule.getRuleId());
                if (null != afsRuleInfo) {
                    afsRuleInfoService.deActiveRule(afsRuleInfo.getId());//规则失效
                    log.info("--------------------规则【" + afsRuleInfo.getId() + "】已失效----------------->");
                }
            }
        }
    }

    /**
     * @param
     * @description 停用规则
     * @author yk.Li
     * @date 2020/7/6
     */
    public void deActiveRule(String id) {
        /**先跑规则修改业务数据，再修改规则状态*/
        this.removeLockContractByRule(id);
        //设为停用
        LoanSuspendRule loanSuspendRule = this.getById(id);
        if (null != loanSuspendRule) {
            loanSuspendRule.setIsEnable(WhetherEnum.NO.getCode());
            this.updateById(loanSuspendRule);
            //设置规则失效
            AfsRuleInfo afsRuleInfo = afsRuleInfoService.getById(loanSuspendRule.getRuleId());
            if (null != afsRuleInfo) {
                afsRuleInfoService.deActiveRule(afsRuleInfo.getId());//规则失效
            }
        }
    }
    public void removeLockContractByRule(String id){
        //设为停用
        LoanSuspendRule loanSuspendRule = this.getById(id);
        if (null != loanSuspendRule) {
            AfsRuleInfo afsRuleInfo = afsRuleInfoService.getById(loanSuspendRule.getRuleId());
            if (null != afsRuleInfo) {
                List<CaseContractInfo> caseContractInfoList = caseContractInfoService.list(Wrappers.<CaseContractInfo>query().lambda()
                        .eq(CaseContractInfo::getIsLock, WhetherEnum.YES.getCode()));
                caseContractInfoList.forEach(contractInfo -> {
                    log.info("合同{}:解除拦截暂停检测开始执行...", contractInfo.getContractNo());
                    try {
                        JSONObject runParam = ruleAtomDataService.getCommonAtomRunParamsLoan(contractInfo.getContractNo());
                        log.info("合同{}:解除拦截暂停规则报文：{}", contractInfo.getContractNo(), runParam);
                        RuleRunResult result = RuleHelper.runRule(runParam, afsRuleInfo.getRuleNo());
                        if (result.getHit()) {
                            List<CasePriorityRecord> records=casePriorityRecordService.list(Wrappers.<CasePriorityRecord>lambdaQuery()
                                    .eq(CasePriorityRecord::getContractNo,contractInfo.getContractNo()).orderByDesc(CasePriorityRecord::getCreateTime));
                            String priority=PriorityEnum.ORDINARY.getCode();//默认优先级5
                            if(!org.springframework.util.CollectionUtils.isEmpty(records)&&records.size()>1) {
                                String hisPriority=records.get(1).getPriority();
                                //如果有历史优先级，恢复之前的优先级
                                if(!hisPriority.equals(PriorityEnum.LOWEST.getCode())){
                                    priority=hisPriority;
                                }
                            }
                            if(StringUtils.isNotBlank(contractInfo.getRemarks())){
                                String[] remarksList = contractInfo.getRemarks().split(";");
                                if(CollectionUtils.isNotEmpty(Arrays.asList(remarksList)) && remarksList.length==1){
                                    contractInfo.setLockDegree(LockDegreeEnum.NORMAL.getValue());
                                    contractInfo.setIsLock(WhetherEnum.NO.getCode());
                                    contractInfo.setPriority(casePriorityChangeService.priorityChange(contractInfo));
                                    contractInfo.setRemarks("");
                                    contractInfo.setLoanSuspendRuleId("");
                                    caseContractInfoService.updateById(contractInfo);
                                }
                                if(CollectionUtils.isNotEmpty(Arrays.asList(remarksList)) && remarksList.length>1){
                                    String[] suspendRuleIdList = contractInfo.getLoanSuspendRuleId().split(";");
                                    if(CollectionUtils.isNotEmpty(Arrays.asList(suspendRuleIdList)) && suspendRuleIdList.length==1){
                                        contractInfo.setLoanSuspendRuleId("");
                                        contractInfo.setLockDegree(LockDegreeEnum.MEDIUM.getValue());
                                    }
                                    if(CollectionUtils.isNotEmpty(Arrays.asList(suspendRuleIdList)) && suspendRuleIdList.length>1){
                                        String suspendRuleIds = "";
                                        int l=0;
                                        for(int i=0;i<suspendRuleIdList.length;i++){
                                            if(!suspendRuleIdList[i].equals(id)){
                                                LoanSuspendRule suspendRule = this.getById(suspendRuleIdList[i]);
                                                if(ObjectUtils.isNotEmpty(suspendRule) && suspendRule.getLockDegree().equals(LockDegreeEnum.MEDIUM.getValue())){
                                                    l++;
                                                }
                                                suspendRuleIds +=suspendRuleIdList[i]+";";
                                            }
                                        }
                                        if(l>0){
                                            contractInfo.setLockDegree(LockDegreeEnum.MEDIUM.getValue());
                                        } else {
                                            contractInfo.setLockDegree(LockDegreeEnum.LOW.getValue());
                                        }
                                        contractInfo.setLoanSuspendRuleId(suspendRuleIds);
                                    }
                                    String resultRemarks = "";
                                    for(int i=0;i<remarksList.length;i++){
                                        if(!remarksList[i].equals(loanSuspendRule.getLockReason())){
                                            resultRemarks +=remarksList[i]+";";
                                        }
                                    }
                                    contractInfo.setRemarks(resultRemarks);
                                    caseContractInfoService.updateById(contractInfo);
                                }
                            }
                        }
                        log.info("合同{}:解除拦截暂停检测执行结束...",contractInfo.getContractNo());
                    }catch (Exception e){
                        log.error("合同{}:解除拦截暂停检测执行失败！{}",contractInfo.getContractNo(),e);
                    }
                });
            }
        }
    }


    /**
     * @param
     * @description 启用规则
     * @author yk.Li
     * @date 2020/7/6
     */
    public void activeRule(@PathVariable String id) {
        //设为启用
        LoanSuspendRule loanSuspendRule = this.getById(id);
        if (null != loanSuspendRule) {
            loanSuspendRule.setIsEnable(WhetherEnum.YES.getCode());
            this.updateById(loanSuspendRule);
            //激活规则
            AfsRuleInfo afsRuleInfo = afsRuleInfoService.getById(loanSuspendRule.getRuleId());
            if (null != afsRuleInfo) {
                afsRuleInfoService.activeRule(afsRuleInfo.getId(), s -> {
                    SpringContextHolder.getBean(LoanSuspendRuleService.class).lockContractByRule(s);
                    return null;
                },id);//规则生效
            }
        }
    }
    public void lockContractByRule(String id){
        LoanSuspendRule loanSuspendRule = this.getById(id);
        AfsRuleInfo afsRuleInfo = afsRuleInfoService.getById(loanSuspendRule.getRuleId());
        if (null != afsRuleInfo) {
            List<String> removeStatus= new ArrayList<>();
            removeStatus.add(ApplyStatusEnum.LOAN_PRE_APPROVE.getState());
            removeStatus.add(ApplyStatusEnum.LOAN_APPROVE_DONE.getState());
            removeStatus.add(ApplyStatusEnum.LOAN_DISCARD.getState());
            List<CaseContractInfo> caseContractInfoList = caseContractInfoService.list(Wrappers.<CaseContractInfo>query().lambda()
                    .notIn(CaseContractInfo::getApplyStatus, removeStatus));
            if (CollectionUtils.isNotEmpty(caseContractInfoList)) {
                if(loanSuspendRule.getLockDegree().equals(LockDegreeEnum.HEIGHT)){
                    caseContractInfoList.forEach(contractInfo -> {
                        log.info("合同{}:拦截暂停检测开始执行...", contractInfo.getContractNo());
                        try {
                            JSONObject runParam = ruleAtomDataService.getCommonAtomRunParamsLoan(contractInfo.getContractNo());
                            log.info("合同{}:拦截暂停规则报文：{}", contractInfo.getContractNo(), runParam);
                            RuleRunResult result = RuleHelper.runRule(runParam, afsRuleInfo.getRuleNo());
                            if (result.getHit()) {
                                //修改申请状态
                                caseBaseInfoService.update(Wrappers.<CaseBaseInfo>lambdaUpdate()
                                        .eq(CaseBaseInfo::getApplyNo,contractInfo.getApplyNo())
                                        .set(CaseBaseInfo::getBusinessStateIn,AfsEnumUtil.key(BusinessStateInEnum.REPEAL)));
                                //修改案件状态
                                contractInfo.setApplyStatus(ApplyStatusEnum.LOAN_DISCARD.getState());
                                contractInfo.setBusinessStage(BusinessStageEnum.LOAN_DISCARD.getCode());
                                contractInfo.setContractStatus(ContractStatusEnum.contractCancel);
                                caseContractInfoService.updateById(contractInfo);
                                //合同废弃记录
                                CaseApproveRecord lockOprRecord = new CaseApproveRecord();
                                String disposeStaff="";
                                lockOprRecord.setContractNo(contractInfo.getContractNo());
                                lockOprRecord.setUseScene(UseSceneEnum.GENERAL_LOAN.getValue());
                                AfsUser user= SecurityUtils.getUser();
                                if(com.baomidou.mybatisplus.core.toolkit.ObjectUtils.isNotEmpty(user)){
                                    disposeStaff=user.getUserRealName();
                                } else {
                                    disposeStaff="暂停拦截";
                                }
                                lockOprRecord.setDisposeStaff(disposeStaff);
                                lockOprRecord.setApproveSuggest(ApplyStatusEnum.LOAN_DISCARD.getState());
                                lockOprRecord.setApproveSuggestName("合同取消");
                                lockOprRecord.setApproveStartTime(new Date());
                                lockOprRecord.setApproveEndTime(new Date());
                                lockOprRecord.setApproveType(ApproveTypeEnum.CANAEL.getValue());
                                lockOprRecord.setFlowNode(contractInfo.getFlowNode());
                                caseApproveRecordService.save(lockOprRecord);
                                //废弃信息通知进件系统
                                approveLoanInfoService.sendToApplyNotic(contractInfo.getContractNo(),ApplyStatusEnum.LOAN_DISCARD);
                            }
                            log.info("合同{}:拦截暂停检测执行结束...", contractInfo.getContractNo());
                            /**放款审核通过调用玄武*/
                            log.info("{}放款审核通过之后，调用玄武",contractInfo.getContractNo());
                            caseTortoiseService.safeDelaySignFraudHand(contractInfo.getApplyNo(), GwtTortoiseAntiFraudCallStep.AFTER_LOAN_APPLY_END);
                        } catch (Exception e){
                            log.error("合同{}:拦截暂停检测执行失败！{}",contractInfo.getContractNo(),e);
                        }
                    });
                } else {
                    caseContractInfoList.forEach(contractInfo -> {
                        log.info("合同{}:拦截暂停检测开始执行...", contractInfo.getContractNo());
                        try {
                            JSONObject runParam = ruleAtomDataService.getCommonAtomRunParamsLoan(contractInfo.getContractNo());
                            log.info("合同{}:拦截暂停规则报文：{}", contractInfo.getContractNo(), runParam);
                            RuleRunResult result = RuleHelper.runRule(runParam, afsRuleInfo.getRuleNo());
                            if (result.getHit()) {
                                String ruleReamrks ="";
                                if(StringUtils.isBlank(contractInfo.getRemarks())){
                                    ruleReamrks = loanSuspendRule.getLockReason()+";";
                                } else {
                                    ruleReamrks = contractInfo.getRemarks()+loanSuspendRule.getLockReason()+";";
                                }
                                if(loanSuspendRule.getLockDegree().equals(LockDegreeEnum.MEDIUM.getValue())){
                                    contractInfo.setLockDegree(LockDegreeEnum.MEDIUM.getValue());
                                    if(StringUtils.isBlank(contractInfo.getLoanSuspendRuleId())){
                                        contractInfo.setLoanSuspendRuleId(id+";");
                                    } else {
                                        contractInfo.setLoanSuspendRuleId(contractInfo.getLoanSuspendRuleId()+id+";");
                                    }
                                } else {
                                    if(contractInfo.getLockDegree().equals(LockDegreeEnum.NORMAL.getValue())){
                                        contractInfo.setLoanSuspendRuleId(id+";");
                                        contractInfo.setLockDegree(LockDegreeEnum.LOW.getValue());
                                    }
                                }
                                contractInfo.setIsLock(WhetherEnum.YES.getCode());
                                contractInfo.setPriority(casePriorityChangeService.priorityChange(contractInfo));
                                contractInfo.setRemarks(ruleReamrks);
                                caseContractInfoService.updateById(contractInfo);
                            }
                            log.info("合同{}:拦截暂停检测执行结束...", contractInfo.getContractNo());
                        }catch (Exception e){
                            log.error("合同{}:拦截暂停检测执行失败！{}",contractInfo.getContractNo(),e);
                        }
                    });
                }
            }
        }
    }
}
